<script setup lang="ts">
// import geojsonvt from 'geojson-vt'
import mapboxgl from 'mapbox-gl'
import { onMounted } from 'vue'
let map: any = null

const initMapFn = (): void => {
  mapboxgl.accessToken =
    'pk.eyJ1Ijoic2FnaXQtemgiLCJhIjoiY2t0bnl5dDFnMDZ0aTJwcDNsa3N4emF1biJ9.jFO8rJJN-kvaz9vuQ0odKQ'
  const mapOptions = {
    container: 'map',
    zoom: 3,
    center: [7.5, 58],
    // style: 'mapbox://styles/mapbox/light-v10'
    style: 'mapbox://styles/mapbox/streets-v11',

  }
  console.log(11111);

  map = new mapboxgl.Map(mapOptions)
  console.log(22222);


  map.on('load', () => {
    console.log(3333);

    map.addLayer(highlightLayer, 'building')
    const layers = map.getStyle().layers
    console.log(layers.filter(l => l.type === 'custom'))

  })

}
const highlightLayer: any = {
  id: 'highlight',
  type: 'custom',

  onAdd: function (map: any, gl: WebGLRenderingContext) {
    // 顶点 source
    const vertexSource = "" +
      "uniform mat4 u_matrix;" +
      "attribute vec2 a_pos;" +
      "void main() {" +
      "    gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);" +
      "}";

    // 片段 source
    const fragmentSource = "" +
      "void main() {" +
      "    gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);" +
      "}";

    // gl.VERTEX_SHADER: 传递 VERTEX_SHADER 给 createShader 以定义顶点着色器
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);

    /**
     * @description: 用于设置 WebGLShader 着色器（顶点着色器及片元着色器）的GLSL程序代码。
     * @param shader{*} 用于设置程序代码的 WebGLShader （着色器对象）
     * @param source{*} 包含GLSL程序代码的字符串。
     */
    gl.shaderSource(vertexShader!, vertexSource);
    /**
     * @description: 用于编译一个GLSL着色器，使其成为为二进制数据，然后就可以被WebGLProgram对象所使用.
     * @param shader{*} 一个片元或顶点着色器 （WebGLShader）
     */
    gl.compileShader(vertexShader!);


    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader!, fragmentSource);
    gl.compileShader(fragmentShader!);

    /**
     * @description: 用于创建和初始化一个 WebGLProgram 对象。
     */
    this.program = gl.createProgram();
    // 添加预先定义好的顶点着色器和片段着色器
    gl.attachShader(this.program, vertexShader!);
    gl.attachShader(this.program, fragmentShader!);

    /**
     * @description: 链接给定的WebGLProgram，从而完成为程序的片元和顶点着色器准备GPU代码的过程。
     * @param WebGLProgram{*} WebGLProgram
     */
    gl.linkProgram(this.program);

    /**
     * @description: 返回了给定WebGLProgram对象中某属性的下标指向位置。
     * @param WebGLProgram{*} WebGLProgram
     * @param name{*} 需要获取下标指向位置的 DOMString 属性参数名
     * @return Position{*} 位置
     */
    this.aPos = gl.getAttribLocation(this.program, "a_pos");

    // 获取墨卡托
    const helsinki = mapboxgl.MercatorCoordinate.fromLngLat({ lng: 25.004, lat: 60.239 });
    const berlin = mapboxgl.MercatorCoordinate.fromLngLat({ lng: 13.403, lat: 52.562 });
    const kyiv = mapboxgl.MercatorCoordinate.fromLngLat({ lng: 30.498, lat: 50.541 });

    /**
     * @description: 创建一个缓冲区
     */
    this.buffer = gl.createBuffer();

    /**
     * @description: 将缓冲区绑定到目标
     * @param target{*} 目标
     * @param buffer{*} 缓冲区
     */
    // gl.ARRAY_BUFFER: 包含顶点属性的Buffer，如顶点坐标，纹理坐标数据或顶点颜色数据。
    gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);

    /**
     * @description: 初始化Buffer对象的数据存储区。
     * @param target{*} 目标
     * @param size{*} 设定Buffer对象的数据存储区大小。
     * @param srcData{?} 一个ArrayBuffer，SharedArrayBuffer 或者 ArrayBufferView 类型的数组对象，将被复制到Buffer的数据存储区。 如果为null，数据存储区仍会被创建，但是不会进行初始化和定义。
     */
    // gl.STATIC_DRAW: 传递给bufferData，作为关于缓冲区内容是否可能经常使用而不是经常更改的提示。
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
      helsinki.x, helsinki.y,
      berlin.x, berlin.y,
      kyiv.x, kyiv.y,
    ]), gl.STATIC_DRAW);
  },

  render: function (gl: WebGLRenderingContext, matrix: Array<number>) {
    gl.useProgram(this.program); // 使用 program
    gl.uniformMatrix4fv(gl.getUniformLocation(this.program, "u_matrix"), false, matrix); // 组合矩阵
    gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); // 绑定缓冲区
    // 激活属性数组列表中指定索引处的通用顶点属性数组
    gl.enableVertexAttribArray(this.aPos); // 激活位置
    // 绑定当前缓冲区范围到gl.ARRAY_BUFFER,成为当前顶点缓冲区对象的通用顶点属性并指定它的布局(缓冲区对象中的偏移量)。
    gl.vertexAttribPointer(this.aPos, 2, gl.FLOAT, false, 0, 0);
    // 启用混色
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3);
  }
};

onMounted(() => initMapFn())



</script>

<template>
  <div id="map"></div>
</template>

<style>
#map {
  width: 1000px;
  height: 500px;
}
</style>